home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 August (Alt) / CHIP 2005-08.1.iso / program / torrent / tracker.exe / tracker.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-05-05  |  7.2 KB  |  317 lines

  1. /**
  2.  **    File ......... tracker.cpp
  3.  **    Published ....  2004-04-20
  4. **/
  5. /*
  6. Copyright (C) 2004  grymse@alhem.net
  7.  
  8. This program is free software; you can redistribute it and/or
  9. modify it under the terms of the GNU General Public License
  10. as published by the Free Software Foundation; either version 2
  11. of the License, or (at your option) any later version.
  12.  
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with this program; if not, write to the Free Software
  20. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21. */
  22. #include <ListenSocket.h>
  23. #include <signal.h>
  24. #include "MyHandler.h"
  25. #include "TrackerSock.h"
  26. #include "MyMinderSocket.h"
  27. #include "MyMinionSocket.h"
  28.  
  29. #define DEB(x)
  30.  
  31.     bool quit = false;
  32.  
  33.  
  34. void top(MyHandler& h)
  35. {
  36.     std::string msg = "Tip_" + Utility::l2string(static_cast<MinderHandler&>(h).GetHostId());
  37.     static_cast<MinderHandler&>(h).SendMessage(Utility::base64(msg));
  38.     unlink("top_map.dot");
  39.     FILE *fil;
  40.     if ((fil = fopen("top_map.dot","wt")) != NULL)
  41.     {
  42.         fprintf(fil,"digraph \"G\" {\n");
  43.         fprintf(fil,"\tedge [arrowhead=open]\n");
  44. #ifdef _WIN32
  45.         std::string os = "Win32";
  46. #else
  47.         std::string os = "Linux";
  48. #endif
  49.         fprintf(fil,"\t\"%ld\" [label=\"%ld\\n%s\\n%s\" style=filled fillcolor=\"#e0e0e0\"]\n",
  50.             static_cast<MinderHandler&>(h).GetHostId(),
  51.             static_cast<MinderHandler&>(h).GetHostId(),
  52.             h.GetVersion().c_str(),
  53.             os.c_str());
  54.         static_cast<MinderHandler&>(h).Tops(fil);
  55.         fclose(fil);
  56.     }
  57. }
  58.  
  59.  
  60. void sigint(int s) /* save+quit */
  61. {
  62.     fprintf(stderr,"shutting down\n");
  63.     quit = true;
  64. }
  65.  
  66.  
  67. void sigpipe(int s)
  68. {
  69. }
  70.  
  71.  
  72. void reg_minder(MyHandler& h,const std::string& cmd)
  73. {
  74.     MyMinderSocket *m = new MyMinderSocket(h,h.GetString("server/announce_url") );
  75.     m -> Init();
  76.  
  77.     m -> Function(cmd); // Hello / Goodbye
  78.     m -> SetDeleteByHandler(true);
  79.     m -> Open(h.GetString("minder/host"),h.GetInt("minder/port"));
  80.     h.Add(m);
  81.     m -> SetLocalIpPort(h.GetLocalAddress(),h.GetLocalPort());
  82.     if (!m -> Connecting()) // connected
  83.     {
  84.         m -> SendHello();
  85.     }
  86.  
  87. }
  88.  
  89.  
  90. void connect(MyHandler& h)
  91. {
  92.     if (h.Count() < h.GetInt("minion/max") )
  93.     {
  94.         ipaddr_t a;
  95.         port_t p;
  96.         std::string key;
  97.         long host_id;
  98.         if (h.GetHost(a,p,key,host_id))
  99.         {
  100.             MinionSocket *tmp = new MyMinionSocket(h,key,a,p);
  101.             tmp -> Init();
  102.             ipaddr_t my_ip;
  103.             port_t my_port;
  104.             h.GetMyIpPort(my_ip, my_port);
  105.             tmp -> SetMyIpPort(my_ip,my_port);
  106.             tmp -> SetRemoteHostId(host_id);
  107.             {
  108.                 std::string t;
  109.                 tmp -> l2ip(a,t);
  110. DEB(                printf("Connect to:  %s:%d\n",t.c_str(),p);)
  111.             }
  112.             if (tmp -> Open(a,p))
  113.             {
  114.                 tmp -> SetDeleteByHandler(true);
  115.                 h.Add(tmp);
  116.                 //
  117.                 tmp -> SendHello("Hello");
  118.             }
  119.             else
  120.             if (tmp -> Connecting())
  121.             {
  122.                 tmp -> SetDeleteByHandler(true);
  123.                 // check OnConnect
  124.                 h.Add(tmp);
  125.             }
  126.             else
  127.             {
  128.                 delete tmp;
  129.             }
  130.         }
  131.         else
  132.         {
  133. DEB(            printf("h.GetHost() failed?\n");)
  134.         }
  135.     }
  136. }
  137.  
  138.  
  139. //////// overrides config file
  140. /*
  141. --port <arg>
  142.           Port to listen on. (defaults to 80)
  143.           OK
  144.  
  145. --dfile <arg>
  146.           file to store recent downloader info in
  147.  
  148. --bind <arg>
  149.           ip to bind to locally (defaults to '')
  150.           OK
  151.  
  152. --socket_timeout <arg>
  153.           timeout for closing connections (defaults to 15)
  154.  
  155. --save_dfile_interval <arg>
  156.           seconds between saving dfile (defaults to 300)
  157.  
  158. --timeout_downloaders_interval <arg>
  159.           seconds between expiring downloaders (defaults to 2700)
  160.           OK
  161.  
  162. --reannounce_interval <arg>
  163.           seconds downloaders should wait between reannouncements (defaults to
  164.           1800)
  165.           OK
  166.  
  167. --response_size <arg>
  168.           number of peers to send in an info message (defaults to 50)
  169.           OK
  170.  
  171. --timeout_check_interval <arg>
  172.           time to wait between checking if any connections have timed out
  173.           (defaults to 5)
  174.           OK
  175.  
  176. --nat_check <arg>
  177.           whether to check back and ban downloaders behind NAT (defaults to 1)
  178.  
  179. --min_time_between_log_flushes <arg>
  180.           minimum time it must have been since the last flush to do another one
  181.           (defaults to 3.0)
  182.  
  183. --allowed_dir <arg>
  184.           only allow downloads for .torrents in this dir (defaults to '')
  185.  
  186. --parse_allowed_interval <arg>
  187.           minutes between reloading of allowed_dir (defaults to 15)
  188.  
  189. --show_names <arg>
  190.           whether to display names from allowed dir (defaults to 1)
  191.  
  192. --favicon <arg>
  193.           file containing x-icon data to return when browser requests
  194.           favicon.ico (defaults to '')
  195.  
  196. --only_local_override_ip <arg>
  197.           ignore the ip GET parameter from machines which aren't on local
  198.           network IPs (defaults to 1)
  199.  
  200. --logfile <arg>
  201.           file to write the tracker logs, use - for stdout (default) (defaults
  202.           to '')
  203.  
  204. --allow_get <arg>
  205.           use with allowed_dir; adds a /file?hash={hash} url that allows users
  206.           to download the torrent file (defaults to 0)
  207.  
  208. --keep_dead <arg>
  209.           keep dead torrents after they expire (so they still show up on your
  210.           /scrape and web page) (defaults to 0)
  211.  
  212. --max_give <arg>
  213.           maximum number of peers to give with any one request (defaults to
  214.           200)
  215. */
  216.  
  217.  
  218. int main(int argc,char *argv[])
  219. {
  220.     MyHandler h( "config.xml" );
  221.     ListenSocket<TrackerSock> l(h);
  222.     ListenSocket<MyMinionSocket> l3(h);
  223.  
  224.     signal(SIGINT, (__sighandler_t)sigint);
  225.     signal(SIGHUP, (__sighandler_t)sigint);
  226.     signal(SIGTERM,(__sighandler_t)sigint);
  227.     signal(SIGPIPE, (__sighandler_t)sigpipe);
  228.  
  229.     // http tracker
  230.     if (h.GetString("server/type") == "normal")
  231.     {
  232.         std::string bind = h.GetString("server/bind");
  233.         port_t port = h.GetInt("server/port");
  234.         int queue_size = h.GetInt("server/queue_size");
  235.         {
  236.             if (l.Bind(bind,port,queue_size))
  237.             {
  238.                 return -1;
  239.             }
  240.             h.Add(&l);
  241.         }
  242.     }
  243.     else
  244.     if (h.GetString("server/type") == "ssl")
  245.     {
  246.         printf("Tracker type not implemented: 'ssl'\n");
  247.         exit(-1);
  248.     }
  249.     else
  250.     {
  251.         printf("Tracker type not supported: '%s'\n",h.GetString("server/type").c_str());
  252.         exit(-1);
  253.     }
  254.     // minion
  255.     {
  256.         std::string bind = h.GetString("minion/bind");
  257.         port_t port = h.GetInt("minion/port");
  258.         while (l3.Bind(port))
  259.         {
  260.             port++;
  261.         }
  262.         h.Add(&l3);
  263.         h.SetLocalPort(port);
  264.     }
  265.     // main loop
  266.     {
  267.         time_t t = time(NULL);  // send peer list (update)
  268.         time_t tc = time(NULL); // connect
  269.         time_t tm = time(NULL); // reg_minder
  270.         time_t tt = time(NULL); // top
  271.         time_t td = time(NULL); // dropped
  272.         reg_minder(h,"Hello");
  273.         h.Select(1,0);
  274.         while (h.GetCount() && !quit)
  275.         {
  276.             h.Select(1,0);
  277.             time_t t2 = time(NULL);
  278.             if (t2 - tc > h.GetInt("minion/connect_interval") && h.GetInt("minion/connect_interval") )
  279.             {
  280.                 tc = t2;
  281.                 connect(h);
  282.             }
  283.             if (t2 - t > h.GetInt("minion/update_interval"))
  284.             {
  285.                 t = t2;
  286.                 h.SendList();
  287.             }
  288.             if (t2 - tm > 15 * 60)
  289.             {
  290.                 tm = t2;
  291.                 reg_minder(h,"Hello");
  292.             }
  293.             if (t2 - tt > h.GetInt("minion/top_interval") && h.GetInt("minion/top_interval") ) // var femte minut
  294.             {
  295.                 tt = t2;
  296.                 top(h);
  297.             }
  298.             if (t2 - td > h.GetInt("server/timeout_check_interval") )
  299.             {
  300.                 td = t2;
  301.                 h.CheckDropped();
  302.             }
  303.         }
  304.     }
  305.     // shutdown
  306.     {
  307.         reg_minder(h,"Goodbye");
  308.         h.Select(1,0);
  309.         while (h.MinderSockets())
  310.         {
  311.             h.Select(1,0);
  312.         }
  313.     }
  314. }
  315.  
  316.  
  317.